package moduleFrame
{
	import flash.utils.getQualifiedClassName;
	
	import moduleFrame.interfaces.IMapComposite;
	import moduleFrame.interfaces.IMaper;

	/**
	 * 用于组合映射
	 * @author Pelephone
	 */
	public class MapComposite extends Maper implements IMapComposite
	{
		/**
		 * 绑定用于哈希映射单例<String,Object>
		 * 普通的哈希键值存储对象
		 */
		protected var _mapHm:Object;
		
		/**
		 * 构造映射组合
		 * @param mapName 映射名
		 * @param parent 父类
		 */
		public function MapComposite(aliasName:String=null)
		{
			_mapHm = {};
//			_singlenMap = {};
			getMapIndex();
			super(aliasName);
		}
		
		/**
		 * 通过类Class获取单例，此方法会自动生成对象;
		 * @param map
		 */
		public function getMapSinglen(cls:Class):*
		{
			var clsName:String = getQualifiedClassName(cls);
			if(hasChildMaper(clsName)) return getChildMaper(clsName);
			var obj:Object = new cls();
			_mapHm[clsName] = obj;
			return obj;
		}
		
		/**
		 * 将对象通过唯一名单例映射在模块里面
		 * @param maper 要映射的对象
		 * @param aliasName 映射在组合上的名,如果为空的话，自动设置绑定对象名为反射的路径
		 * @param mapParent 父类如果为空就父类是当前类
		 */
		public function registerMaper(maper:IMaper,aliasName:String=null,mapParent:IMapComposite=null):void
		{
			if(maper===this){
				throw Error("不能注册自己!");
			}
			if(!aliasName && maper.getName()==null)
			{
				aliasName = getQualifiedClassName(maper);
				maper.setName(aliasName);
			}
			else if(maper.getName()!=null)
				aliasName = maper.getName();
			
			if(hasChildMaper(aliasName)){
				var mid:int = getMapIndex();
				trace(aliasName,"已有映射有同名单例!,自动以新别名",(aliasName+mid),"映射");
				aliasName = aliasName + mid;
				maper.setName(aliasName);
			}
			_mapHm[aliasName] = maper;
			mapParent = mapParent || this;
			maper.setMapParent(mapParent);
			maper.onRegister();
		}
		
		/**
		 * 是该名字是否定有对象
		 * @param bindName
		 * @return 
		 */
		public function hasChildMaper(aliasName:String):Boolean
		{
			return _mapHm[aliasName]!=null;
		}
		
		/**
		 * 通过别名获取映射在模块上的对象
		 * @param aliasName 别名
		 * @return 
		 */
		public function getChildMaper(aliasName:String):IMaper
		{
			return _mapHm[aliasName] as IMaper;
		}
		
		/**
		 * 通过对象自动反射出路径做为别名获取映射上的单例
		 * @param refObj 要反射别名的Class对象
		 */
		public function getChildMaperOf(refObj:Object):*
		{
			var res:* = getChildMaper(String(refObj));
			if(res) return res;
			
			var aliasName:String = getQualifiedClassName(refObj);
			return getChildMaper(aliasName);
		}
		
		/**
		 * 通过别名移除映射在模块上的对象
		 * @param aliasName 单例别名
		 */
		public function removeChildMaperByName(aliasName:String):IMaper
		{
			var maper:IMaper = _mapHm [ aliasName ] as IMaper;
			if ( maper ) 
			{
				_mapHm[ aliasName ] = null;
//				maper.safeRemove();
				maper.onRemove();
				delete _mapHm[aliasName];
			}
			return maper;
		}
		
		/**
		 * 通过对象移出映射
		 * @param refObj
		 */
		public function removeChildMaper(maper:IMaper):void
		{
//			var hasSg:Boolean = hasSingleton(maper.getName());
//			var aliasName:String;
//			if(hasSg) aliasName = maper.getName();
//			else aliasName = getQualifiedClassName(refObj);
			
			removeChildMaperByName(maper.getName());
		}
		
		
		override public function dispose():void
		{
			for (var aliName:String in _mapHm) 
			{
				var mcp:IMaper = _mapHm[aliName] as IMaper;
				mcp.dispose();
				delete _mapHm[aliName];
			}
			if(getMapParent()) 
				getMapParent().removeChildMaper(this);
			_mapHm = null;
//			_singlenMap = null;
			super.dispose();
		}
		
		/**
		 * 模块数标识,每新建一个模块计数会加1
		 */
		private static var mapIndex:int = 0;
		private static function getMapIndex():int
		{
			return ++mapIndex;
		}
	}
}